package com.tlgen.orm.utils.orm;

import com.tlgen.orm.annotation.AutoFill;
import com.tlgen.orm.enums.FillType;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class AutoFillUtils {

    /**
     * 设置字段值(带操作类型检查)
     * @param entity 实体对象
     * @param fieldName 字段名
     * @param fieldValue 字段值
     * @param operationType 操作类型
     */
    public static void setFieldValue(Object entity, String fieldName, Object fieldValue, FillType operationType) {
        if (entity == null || fieldName == null) {
            return;
        }

        // 获取实体类及其所有父类
        List<Class<?>> classes = getAllSuperClasses(entity.getClass());

        for (Class<?> clazz : classes) {
            try {
                Field field = clazz.getDeclaredField(fieldName);
                AutoFill autoFill = field.getAnnotation(AutoFill.class);

                // 检查操作类型是否匹配
                if (autoFill != null && containsOperation(autoFill.value(), operationType)) {
                    boolean accessible = field.isAccessible();
                    if (!accessible) {
                        field.setAccessible(true);
                    }
                    field.set(entity, fieldValue);
                    field.setAccessible(accessible);
                    return; // 找到并赋值后立即返回
                }
            } catch (NoSuchFieldException e) {
                // 继续在父类中查找
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Failed to set field value: " + fieldName, e);
            }
        }
    }

    /**
     * 检查操作类型是否存在于注解值中
     */
    private static boolean containsOperation(FillType[] annotationTypes, FillType operationType) {
        for (FillType type : annotationTypes) {
            if (type == operationType) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取所有父类(包含自身)
     */
    private static List<Class<?>> getAllSuperClasses(Class<?> clazz) {
        List<Class<?>> classes = new ArrayList<>();
        Class<?> current = clazz;
        while (current != null && current != Object.class) {
            classes.add(current);
            current = current.getSuperclass();
        }
        return classes;
    }

}